<?php 

class profile_model extends CI_Model {
	
	private $USER_TABLE = 'users';
	private $GAMESET_TABLE = 'game_sets';
	
	private $RECENT_GAMES_COUNT;
	
	function __construct(){
		parent::__construct();
		
		//Load challenge settings
		$this->config->load('profile_settings');
		
		$this->RECENT_GAMES_COUNT = $this->config->item('recent_games_count');
	}
	
	/**
	 * Retrieves all the data for the user with the given account name
	 *
	 * @param $account_name - Name of the user's account
	 */
	function get_data($account_name){
		
		$this->db->where('account', $account_name);
		$query = $this->db->get($this->USER_TABLE);

		if ($query->num_rows == 1)
			return $query->row_array();
			
		return false;
	}
	
	/** Gets a single field for the specified user */
	function get_field($account_name, $field){
		$this->db->select(array( 0 => $field));
		$this->db->where('account', $account_name);
		$query = $this->db->get($this->USER_TABLE);
		if ($query->num_rows == 0) return false;
		
		$data = $query->row_array();
	
		return $data[$field];
	}
	
	
	/** Updates a single field for the specified user */
	function update_field($account_name, $field, $value){
		$data = array();
		$data[$field] = $value;
		$this->db->where('account', $account_name);
		$query = $this->db->update($this->USER_TABLE, $data);
	}
	
	/**
	 * Updates the given user's profile.
	 *
	 * @param $account_name - Name of the account to update
	 * @param $data - Modified account information
	 */
	function update_profile($account_name, $data){
		// Load gateway model in order to confirm current password and set new password.
		$this->load->model('gateway_model');
		
		// Only update is password was correct or not required
		if($data['password'] == '' || $this->gateway_model->confirmPassword($account_name, $data['password'])){
			//Remove password - will be readded if password change was requested
			unset($data['password']);
			
			// Check if new password was requested
			if(strlen($data['newpassword']) > 3){
				// Create new salt and password
				$salt = random_string('alnum', 32);
				
				$data['salt'] = $salt;
				$data['password'] = $this->gateway_model->encryptPassword($data['newpassword'], $salt);
			}
			
			unset($data['newpassword']); //Field does not exists in db, must be removed before update
			
			// Update row with new info
			$this->db->where('account', $account_name);
			return $this->db->update($this->USER_TABLE, $data);
		}
	}

	// Get this user's recently played games
	function get_recent_games($account_name) {
		$select_games = array(0 => 'game_set_id', 1 => 'player1', 2 => 'player2', 3 => 'player1_wins', 4 => 'player2_wins');
        $this->db->select($select_games);
        $this->db->where('status', 'finished');                       // Comment out for testing while there are no finished game sets
        $this->db->where('player1', $account_name);
        $this->db->or_where('status', 'finished');
        $this->db->where('player2', $account_name);
        $this->db->order_by('date_complete', 'desc'); //TODO: This should actually be date completed
		$this->db->limit($this->RECENT_GAMES_COUNT);
                
        $query = $this->db->get($this->GAMESET_TABLE);
        $rows = $query->result_array();
	
        return $rows;
	}
	
	/** 
	 * This function updates the players scores
	 * parameters are player names winner then loser
	 */
	function update_score($winner, $loser){
		$wScore = $this->get_field($winner, 'score');
		$lScore = $this->get_field($loser, 'score');
		
		//K values
		$Kw = $wScore < 2400 ? ($wScore < 2100 ? 32 : 24) : 16;
		$Kl = $lScore < 2400 ? ($lScore < 2100 ? 32 : 24) : 16;
		//EOL calculation
		$Qw = 10 ^ ($wScore / 400.0);
		$Ql = 10 ^ ($lScore / 400.0);
		
		$Ew = $Qw / ($Qw + $Ql);
		$El = $Ql / ($Qw + $Ql);
		
		$wNewScore = $wScore + $Kw * (1 - $Ew);
		$lNewScore = $lScore + $Kl * (0 - $El);
		
		$lNewScore = $lNewScore < 100 ? 100  : $lNewScore;
		
		//rank update
		$this->update_field($winner, 'score', $wNewScore);
		$this->update_field($loser, 'score', $lNewScore);
		
		//update wins and losses
		$ww = $this->get_field($winner, 'ladder_wins');
		$ll = $this->get_field($loser, 'ladder_losses');
		
		$this->update_field($winner, 'ladder_wins', $ww+1);
		$this->update_field($loser, 'ladder_losses', $ll+1);
		
		
		//for debug
		//return 'Winner: '.$winner.' oldScore: '.$wScore.' newScore: '.$wNewScore.'<br/>'.'Loser: '.$loser.' oldScore: '.$lScore.' newScore: '.$lNewScore;
	
	
	}

	/**
	 * This function, run every time a profile loads, checks to see if 
	 * a challenge has been ignored for over a week, which results in 
	 * an auto-rejection.
	 */
	function timeout_check($challenge) {

		$time_elapsed = time() - human_to_unix($challenge->DATE_ISSUED);
		
		if ($time_elapsed/(60*60*24) > 7) {
			$challenge->accept_challenge(false);
			return false;
		} else {
			return true;
		}
		
	}
	
}
